home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / C ƒ / CITADEL BBS 'C' SRC / NETCALL.C < prev    next >
C/C++ Source or Header  |  1987-01-14  |  17KB  |  603 lines

  1. /************************************************************************/
  2. /*                netcall.c                */
  3. /*                                    */
  4. /*    Networking call functions.                    */
  5. /************************************************************************/
  6.  
  7. /************************************************************************/
  8. /*                history                 */
  9. /*                                    */
  10. /* 86Aug20 HAW    History not maintained due to space problems.        */
  11. /************************************************************************/
  12.  
  13. #include "ctdl.h"
  14.  
  15. /************************************************************************/
  16. /*                contents                */
  17. /*                                    */
  18. /************************************************************************/
  19.  
  20. /************************************************************************/
  21. /*           External variable declarations in NET.C        */
  22. /************************************************************************/
  23. char            inReceive;
  24.  
  25. extern FILE        *netMisc;
  26. extern FILE        *netLog;
  27. extern ulong        roomHiMsgs[MAXROOMS];
  28. extern unsigned char    sectBuf[SECTSIZE + 5];
  29. extern int        counter;
  30. extern int        callSlot;
  31. extern int        FinHour, FinMinute;
  32. extern label        normed, callerName, callerId;
  33. char            checkNegMail;
  34. extern char        processMail;
  35.  
  36. extern int noKill, errCount;
  37.  
  38. char         normId(), getNetMessage();
  39. char         callOut();
  40. unsigned char     inp();
  41.  
  42. extern struct nodeRoomsTab *sharedRooms;
  43.  
  44. extern struct config    cfg;        /* Lots an lots of variables    */
  45. extern struct logBuffer logBuf;     /* Person buffer        */
  46. extern struct aRoom    roomBuf;    /* Room buffer            */
  47. extern struct rTable    roomTab[];
  48. extern struct msgB    msgBuf,tempMess;
  49. extern struct netBuffer netBuf;
  50. extern struct netTable    *netTab;
  51. extern FILE        *upfd;
  52. extern int        thisNet;
  53. extern char        onConsole;
  54. extern char        loggedIn;    /* Is we logged in?        */
  55. extern char        outFlag;    /* Output flag            */
  56. extern char        haveCarrier;    /* Do we still got carrier?    */
  57. extern unsigned char    modStat;    /* Needed so we don't die    */
  58. extern char        usingWCprotocol;/* WC flag            */
  59. extern char        WCError;
  60.  
  61. char *chMailTemplate = "%c:chkMail.$$$";
  62.  
  63. /************************************************************************/
  64. /*           External function definitions for NET.C        */
  65. /************************************************************************/
  66. FILE *safeopen();
  67. FILE *fopen();
  68. char *realloc();
  69. char *index();
  70. long getNumber();
  71.  
  72. /************************************************************************/
  73. /*    caller() we've called and got carrier, so let's goferit     */
  74. /************************************************************************/
  75. caller()
  76. {
  77.     inReceive = FALSE;
  78.     processMail = FALSE;
  79.     checkNegMail = FALSE;
  80.  
  81.     splitF(netLog, "Have Carrier\n");
  82.     caller_stabilize();
  83.  
  84.     if (!haveCarrier) return ;    /* Abort */
  85.  
  86.     splitF(netLog, "Have stabilized call with receiver\n");
  87.     sendId();
  88.     if (!haveCarrier) return ;    /* Abort */
  89.  
  90.     sendStuff(FALSE);
  91.  
  92.     while (gotCarrier()) ;
  93.  
  94.     doResults();
  95.  
  96.     splitF(netLog, "Call to %s finished successfully\n\n", netBuf.netName);
  97.  
  98.     modStat = haveCarrier = FALSE;
  99. }
  100.  
  101. /************************************************************************/
  102. /*    sendStuff() assume role of sender                */
  103. /************************************************************************/
  104. sendStuff(reversed)
  105. char reversed;
  106. {
  107.     if (callSlot != ERROR) {
  108.     if (netBuf.nbflags.normal_mail) {
  109.         sendMail();
  110.         if (!haveCarrier) return ;    /* Abort */
  111.         checkMail();
  112.     }
  113.     if (!haveCarrier) return ;  /* Abort */
  114.  
  115.     if (netBuf.nbflags.room_files)
  116.         askFiles();
  117.     if (!haveCarrier) return ;  /* Abort */
  118.  
  119.     sendSharedRooms();
  120.     if (!haveCarrier) return ;  /* Abort */
  121.  
  122.     roleReversal(reversed);
  123.     if (!haveCarrier) return ;  /* Abort */
  124.     }
  125.  
  126.     sendHangUp();
  127. }
  128.  
  129. /************************************************************************/
  130. /*    roleReversal() hokay, into drag                 */
  131. /************************************************************************/
  132. roleReversal(reversed)
  133. {
  134.     struct cmd_data cmds;
  135.  
  136.     if (reversed) return ;
  137.     if (!netBuf.nbflags.local) return ;
  138.  
  139.     splitF(netLog, "Reversing roles\n");
  140.  
  141.     zero_struct(cmds);
  142.     cmds.command = ROLE_REVERSAL;
  143.     if (!sendNetCommand(&cmds, "role reversal"))
  144.     return;
  145.  
  146.     rcvStuff(TRUE);
  147.     reply(GOOD, "");
  148. }
  149.  
  150. /************************************************************************/
  151. /*    caller_stabilize() Tries to stabilize the call --        */
  152. /*               baud is already set                */
  153. /************************************************************************/
  154. caller_stabilize()
  155. {
  156.     int Time, i, j;
  157.     int x1, x2, x3;
  158.  
  159.     pause(200);     /* Pause a full 2 seconds            */
  160.     while (MIReady())    inp();            /* Clear garbage    */
  161.     for (Time = 0; Time < 20 && gotCarrier(); Time++) {
  162.     if (cfg.debug) splitF(netLog, ".");
  163.     outMod(7);
  164.     pause(10);
  165.     outMod(13);
  166.     pause(10);
  167.     outMod(69);
  168.     for (j = 0; j < INTERVALS && !MIReady(); j++)
  169.         for (i = 0; i < 250 && !MIReady(); i++)
  170.         shortPause();
  171.     if (MIReady()) {
  172.         x1 = receive(2);
  173.         x2 = receive(2);
  174.         if (x2 != ERROR) x3 = receive(2);
  175.         if (x1 == 248 &&
  176.         x2 == 242 &&
  177.         x3 == 186) {
  178.         outMod(ACK);
  179.         if (cfg.debug) splitF(netLog, "ACKing, Call stabilized\n");
  180.         return;
  181.         }
  182.         else if (cfg.debug) splitF(netLog, "%d %d %d\n", x1, x2, x3);
  183.     }
  184.     }
  185.     splitF(netLog, "Call not stabilized\n");
  186.     modStat = haveCarrier = FALSE;
  187.     interpret(cfg.pHangUp);
  188. }
  189.  
  190. /************************************************************************/
  191. /*    sendId() Sends ID to the receiver                */
  192. /************************************************************************/
  193. sendId()
  194. {
  195.     char *reason;
  196.     char message[40];
  197.  
  198.     if (!gotCarrier()) return modStat = haveCarrier = FALSE;
  199.     if (!doWC(STARTUP)) {
  200.     no_good("Couldn't transfer ID to %s!", TRUE);
  201.     modStat = haveCarrier = FALSE;
  202.     interpret(cfg.pHangUp);
  203.     return;
  204.     }
  205.  
  206.     mWCprintf("%s", cfg.codeBuf + cfg.nodeId  );
  207.     mWCprintf("%s", cfg.codeBuf + cfg.nodeName);
  208.  
  209.     if (WCError) {
  210.     if (!gotCarrier()) {
  211.         modStat = haveCarrier = FALSE;
  212.         reason = "carrier loss";
  213.     }
  214.     else reason = "WC abort: 10 errors or CANCEL";
  215.     doWC(FINISH);
  216.     strCpy(message, "Couldn't transfer ID to %s! ");
  217.     strCat(message, reason);
  218.     no_good(message, TRUE);
  219.     return;
  220.     }
  221.     doWC(FINISH);
  222. }
  223.  
  224. /************************************************************************/
  225. /*    sendMail()  send normal mail to receiver            */
  226. /************************************************************************/
  227. sendMail()
  228. {
  229.     struct cmd_data cmds;
  230.     int i, nor_mail;
  231.     char *reason, message[50];
  232.  
  233.     if (!gotCarrier()) return modStat = haveCarrier = FALSE;
  234.     splitF(netLog, "Sending normal mail\n");
  235.  
  236.     zero_struct(cmds);
  237.     cmds.command = NORMAL_MAIL;
  238.     if (!sendNetCommand(&cmds, "normal mail"))
  239.     return;
  240.  
  241.     if (!doWC(STARTUP)) {
  242.     no_good("Couldn't start Mail transfer to %s!", TRUE);
  243.     modStat = haveCarrier = FALSE;
  244.     interpret(cfg.pHangUp);
  245.     return;
  246.     }
  247.     nor_mail = s_m_n();        /* Send normal mail       */
  248.  
  249.     if (WCError) {
  250.     if (!gotCarrier()) {
  251.         modStat = haveCarrier = FALSE;
  252.         reason = "carrier loss";
  253.     }
  254.     else reason = "WC abort: 10 errors or CANCEL";
  255.     doWC(FINISH);
  256.     strCpy(message, "Couldn't transfer ID to %s! ");
  257.     strCat(message, reason);
  258.     no_good(message, TRUE);
  259.     return;
  260.     }
  261.     else {
  262.     splitF(netLog, "\nSuccessful transfer of %d messages\n", nor_mail);
  263.     netBuf.nbflags.normal_mail = FALSE;
  264.     }
  265.     doWC(FINISH);
  266. }
  267.  
  268. /************************************************************************/
  269. /*    checkMail()  negative acknowledgement on netMail>        */
  270. /************************************************************************/
  271. checkMail()
  272. {
  273.     struct cmd_data cmds;
  274.     int i, nor_mail, putFLChar();
  275.     char *reason, message[50];
  276.  
  277.     if (!gotCarrier()) return modStat = haveCarrier = FALSE;
  278.     splitF(netLog, "Asking for check on normal mail\n");
  279.  
  280.     zero_struct(cmds);
  281.     cmds.command = CHECK_MAIL;
  282.     if (!sendNetCommand(&cmds, "check mail"))
  283.     return;
  284.  
  285.     sPrintf(message, chMailTemplate, cfg.netDisk + 'A');
  286.     upfd = safeopen(message, "wb");
  287.     readFile(putFLChar);
  288.     fclose(upfd);
  289.     checkNegMail = TRUE;    /* Call readNegMail() later */
  290. }
  291.  
  292. /************************************************************************/
  293. /*    readNegMail() reads and processes negative acks         */
  294. /************************************************************************/
  295. readNegMail()
  296. {
  297.     char message[30];
  298.     label author, target, context;
  299.     int whatLog;
  300.     struct logBuffer lBuf;
  301.     int  sigChar;
  302.  
  303.     sPrintf(message, chMailTemplate, cfg.netDisk + 'A');
  304.     if ((netMisc = safeopen(message, "rb")) == NULL) {
  305.     no_good("Couldn't open negative ack file from %s.", TRUE);
  306.     return ;
  307.     }
  308.  
  309.     getRoom(MAILROOM);
  310.     sigChar = getc(netMisc);
  311.     while (sigChar != NO_ERROR && sigChar != EOF && sigChar != EOF) {
  312.     zero_struct(msgBuf);
  313.     strCpy(msgBuf.mbauth, "Citadel");
  314.     getNetStr(author);
  315.     getNetStr(target);
  316.     getNetStr(context);
  317.     switch (sigChar) {
  318.         case NO_RECIPIENT:
  319.         strCpy(msgBuf.mbto, author);
  320.         if (strLen(author) > 0 && getRecipient(&lBuf, &whatLog)) {
  321.             sPrintf(msgBuf.mbtext,
  322. "Your netMail to '%s' (%s) failed because there is no such recipient on %s.",
  323.             target, context, callerName);
  324.             if (putMessage()) noteMessage(&lBuf, whatLog);
  325.             break;
  326.         }
  327.         case UNKNOWN:
  328.         zero_struct(msgBuf);
  329.         sPrintf(msgBuf.mbtext,
  330. "Unknown problems with netMail: author=-%s-,target=-%s-,context=-%s-",
  331.                       author, target, context);
  332.         aideMessage(FALSE);
  333.         break;
  334.         case BAD_FORM:
  335.         sPrintf(msgBuf.mbtext, "Bad netMail sent to %s.", callerName);
  336.         aideMessage(FALSE);
  337.         break;
  338.         default:
  339.         sPrintf(msgBuf.mbtext, "Bad sigChar=%d.", sigChar);
  340.         aideMessage(FALSE);
  341.         break;
  342.     }
  343.     sigChar = getc(netMisc);
  344.     }
  345.     fclose(netMisc);
  346.     unlink(message);
  347. }
  348.  
  349. /************************************************************************/
  350. /*    sendSharedRooms() Sends all shared rooms to receiver        */
  351. /************************************************************************/
  352. sendSharedRooms()
  353. {
  354.     struct cmd_data cmds;
  355.     int msgRover;
  356.     char mess[140];
  357.     extern char *R_SH_MARK;
  358.     int rover;
  359.  
  360.     for (rover = 0; rover < SHARED_ROOMS; rover++) {
  361.     if (!gotCarrier()) {
  362.         modStat = haveCarrier = FALSE;
  363.         return;
  364.     }
  365.     if (isSharedRoom(thisNet, rover) && roomValidate(rover)) {
  366.         if (roomHiMsgs[netRoomSlot(rover)] >
  367.                   netBuf.netRooms[rover].lastMess) {
  368.         getRoom(netRoomSlot(rover));
  369.         zero_struct(cmds);
  370.         cmds.command = NET_ROOM;
  371.         strCpy(cmds.fields[0], roomBuf.rbname);
  372.         splitF(netLog, "Sending %s\n", roomBuf.rbname);
  373.         if (sendNetCommand(&cmds, "shared rooms")) {
  374.             if (!doWC(STARTUP)) {
  375.             no_good("Couldn't start WC for room sharing: %s",
  376.                                    FALSE);
  377.             continue;
  378.             }
  379.             usingWCprotocol = WC_NETWORK;
  380.             for (msgRover = 0; msgRover < MSGSPERRM; msgRover++) {
  381.             if (netBuf.netRooms[rover].lastMess <
  382.                     roomBuf.msg[msgRover].rbmsgNo) {
  383.                 if (findMessage(roomBuf.msg[msgRover].rbmsgLoc,
  384.                      roomBuf.msg[msgRover].rbmsgNo))
  385.                 if (strCmpU(msgBuf.mbaddr, R_SH_MARK) ==
  386.                                 SAMESTRING)
  387.                     printMessage(roomBuf.msg[msgRover].rbmsgLoc,
  388.                      roomBuf.msg[msgRover].rbmsgNo);
  389.             }
  390.             }
  391.             doWC(FINISH);
  392.             usingWCprotocol = WC_NONE;
  393.           netBuf.netRooms[rover].lastMess = roomHiMsgs[netRoomSlot(rover)];
  394.             sharedRooms[thisNet].rooms[rover].lastMess =
  395.                         roomHiMsgs[netRoomSlot(rover)];
  396.         }
  397.         else {
  398.             strCpy(mess, "%s reports: ");
  399.             strCat(mess, sectBuf + 1);
  400.             no_good(mess, FALSE);
  401.             resetNetRoomFlag(rover);
  402.         }
  403.         }
  404.     }
  405.     else resetNetRoomFlag(rover);
  406.     }
  407. }
  408.  
  409. /************************************************************************/
  410. /*    askFiles() ask for file(s) from caller                */
  411. /************************************************************************/
  412. askFiles()
  413. {
  414.     label  data;
  415.     int    putFLChar(), i;
  416.     char   mess[130], *cd, *gcdir();
  417.     char   ambiguous;
  418.     FILE   *temp;
  419.     struct cmd_data cmds;
  420.     struct fl_req file_data;
  421.  
  422.     if (!gotCarrier()) return modStat = haveCarrier = FALSE;
  423.     sPrintf(data, "a:%d.rfl", thisNet);
  424.     data[0] = cfg.netDisk + 'a';
  425.     temp = safeopen(data, "rb");
  426.     if (temp == NULL) {
  427.     no_good("Couldn't open room request file for %s", FALSE);
  428.     netBuf.nbflags.room_files = FALSE;
  429.     }
  430.     else {
  431.     splitF(netLog, "Asking for files\n");
  432.     while (fread(&file_data, sizeof (file_data), 1, temp) == 1 &&
  433.                  gotCarrier()) {
  434.         setSpace(toUpper(file_data.drive) - 'A', "");
  435.         cd = gcdir("");
  436.         if (chdir(file_data.path) != EOF) {
  437.         zero_struct(cmds);
  438.         ambiguous = !(index(file_data.roomfile, '*') == NULL &&
  439.                   index(file_data.roomfile, '?') == NULL);
  440.         cmds.command = (!ambiguous) ? R_FILE_REQ : A_FILE_REQ;
  441.  
  442.         strCpy(cmds.fields[0], file_data.room);
  443.         strCpy(cmds.fields[1], file_data.roomfile);
  444.         splitF(netLog, "%s in %s\n", file_data.roomfile, file_data.room);
  445.         if (!sendNetCommand(&cmds,
  446.          (!ambiguous) ? "single file request" :
  447.                 "multiple file request")) {
  448.             strCpy(mess, "%s reports: ");
  449.             strCat(mess, sectBuf + 1);
  450.             no_good(mess, FALSE);
  451.         }
  452.         else {
  453.             if (ambiguous) multiReceive(file_data.path);
  454.             else {
  455.             upfd = safeopen(file_data.filename, "wb");
  456.             readFile(putFLChar);
  457.             fclose(upfd);
  458.                sPrintf(msgBuf.mbtext, "The file '%s' received from %s.",
  459.                  file_data.filename, netBuf.netName);
  460.             aideMessage(FALSE);
  461.             }
  462.         }
  463.         chdir(cd);
  464.         free(cd);
  465.         }
  466.         setSpace(cfg.homeDisk, "");
  467.     }
  468.     fclose(temp);
  469.     if (gotCarrier()) {
  470.         unlink(data);
  471.         netBuf.nbflags.room_files = FALSE;
  472.     }
  473.     else haveCarrier = modStat = FALSE;
  474.     }
  475. }
  476.  
  477. /************************************************************************/
  478. /*    multiReceive() Receive multiple files                */
  479. /************************************************************************/
  480. multiReceive(subdir)
  481. char *subdir;
  482. {
  483.     int increment(), putFLChar();
  484.     char first = 1;
  485.     char *end;
  486.  
  487.     sPrintf(msgBuf.mbtext, "Following files received from %s: ",netBuf.netName);
  488.     do {
  489.     counter = 0;
  490.     readFile(increment);
  491.     if (!gotCarrier()) return;
  492.     if (sectBuf[0] == 0) {        /* Last file name    */
  493.         end = msgBuf.mbtext + strLen(msgBuf.mbtext);
  494.         sPrintf(end, " (stored in directory %s).", subdir);
  495.         aideMessage(FALSE);
  496.         return;
  497.     }
  498.     if (!first)
  499.         strCat(msgBuf.mbtext, ", ");
  500.     else
  501.         first = FALSE;
  502.     strCat(msgBuf.mbtext, sectBuf);
  503.     upfd = safeopen(sectBuf, "wb");
  504.     readFile(putFLChar);
  505.     fclose(upfd);
  506.     } while (1);
  507. }
  508.  
  509. /************************************************************************/
  510. /*    sendNetCommand() Sends a command to the receiver        */
  511. /************************************************************************/
  512. sendNetCommand(cmds, error)
  513. struct cmd_data *cmds;
  514. char        *error;
  515. {
  516.     int count, increment();
  517.     char errMsg[100];
  518.  
  519.     if (!doWC(STARTUP)) {
  520.     sPrintf(errMsg, "Link failure for %s (system: %%s).", error);
  521.     no_good(errMsg, TRUE);
  522.     modStat = haveCarrier = FALSE;
  523.     interpret(cfg.pHangUp);
  524.     return;
  525.     }
  526.     sendWCChar(cmds->command);
  527.     for (count = 0; count < 4; count++)
  528.     if (cmds->fields[count][0])
  529.         mWCprintf("%s", cmds->fields[count]);
  530.     sendWCChar(0);
  531.     doWC(FINISH);
  532.     counter = 0;
  533.     if (cmds->command == HANGUP && !inReceive) return TRUE;
  534.     readFile(increment);
  535.     if (sectBuf[0] == BAD) return FALSE;
  536.     return TRUE;
  537. }
  538.  
  539. /************************************************************************/
  540. /*    sendHangUp() Send hangup command to receiver            */
  541. /************************************************************************/
  542. sendHangUp()
  543. {
  544.     struct cmd_data cmds;
  545.     int         i;
  546.  
  547.     if (!gotCarrier()) return modStat = haveCarrier = FALSE;
  548.     zero_struct(cmds);
  549.     cmds.command = HANGUP;
  550.     sendNetCommand(&cmds, "HANGUP");
  551. }
  552.  
  553. /************************************************************************/
  554. /*    no_good() does error messages                    */
  555. /************************************************************************/
  556. no_good(str, hup)
  557. char *str;
  558. char hup;
  559. {
  560.     sPrintf(msgBuf.mbtext, str, netBuf.netName);
  561.     if (hup) {
  562.     interpret(cfg.pHangUp);
  563.     modStat = haveCarrier = FALSE;
  564.     }
  565.     aideMessage(FALSE);
  566. }
  567.  
  568. /************************************************************************/
  569. /*    s_m_n() Send mail normal (non-route mail)            */
  570. /************************************************************************/
  571. s_m_n()
  572. {
  573.     FILE  *ptrs;
  574.     char  c;
  575.     label fn;
  576.     ulong id;
  577.     int   val, messCount = 0;
  578.     struct netMLstruct buf;
  579.     unsigned location;
  580.  
  581.     sPrintf(fn, "a:%d.ml", thisNet);
  582.     fn[0] = cfg.netDisk + 'a';
  583.     if ((ptrs = safeopen(fn, "rb")) == NULL) {
  584.     sPrintf(msgBuf.mbtext, "No mail file to send to %s?", netBuf.netName);
  585.     aideMessage(FALSE);
  586.     return 0;
  587.     }
  588.  
  589.     usingWCprotocol = WC_NETWORK;
  590.     while (getMLNet(ptrs, buf)) {
  591.     printMessage(buf.ML_loc, buf.ML_id);
  592.     messCount++;
  593.     }
  594.     usingWCprotocol = WC_NONE;
  595.     fclose(ptrs);
  596.     if (!WCError) {
  597.     unlink(fn);
  598.     return messCount;
  599.     }
  600.     splitF(netLog, "\nUnsuccessful transfer of normal mail\n");
  601.     return 0;
  602. }
  603.